﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Threading;
using DevDefined.OAuth.Framework;
using Lightray.Hattrick.ChppLib;
using Lightray.Hattrick.ChppLib.EntityTypes;
using Lightray.Hattrick.ChppLib.OAuth;

namespace ChppPlay
{
    class Play1
    {
        const string CONSUMER_KEY = "JSbyUK14ITfQDTSQOsHFU-";
        readonly Guid storageId = new Guid("0e28507f-55b1-4515-8465-6329567c5878");
        AutoResetEvent ev = new AutoResetEvent(false);
        DataManager _dataManager;

        class PlayerComparer : EqualityComparer<PlayerScores>
        {
            public override bool Equals(PlayerScores x, PlayerScores y)
            {
                return x.TargetPlayer.ID == y.TargetPlayer.ID;
            }

            public override int GetHashCode(PlayerScores obj)
            {
                return obj.GetHashCode();
            }
        }

        public Play1()
        {
            _dataManager = new DataManager(storageId, "../../../storages", readTokenFromFile(), readSecretFromFile());
            _dataManager.NewDataArrived += new EventHandler<DataManagerEventArgs>(_dataManager_NewDataArrived);
            _dataManager.StartDataManager();
            
            
            

            //calcLineup();
          
            //calc2ndLineup();

            //WebFetcher fetcher = new WebFetcher(readTokenFromFile(), readSecretFromFile())

            ev.WaitOne();                    
        }

        void _dataManager_NewDataArrived(object sender, DataManagerEventArgs e)
        {
            //ev.Set();
           //  calcLineup();
            ////var formation = Calculations.GetBestFormation(e.MyTeam.Players.ToList(), Weather.Unknown, false);

            ////int wingbacks, defenders, wingers, playmakers, forwards;
            ////Calculations.GetPlayerCountPerPosition(formation, out wingbacks, out defenders, out wingers, out playmakers, out forwards);

            //var lineup = Calculations.GetLineup(e.MyTeam.Players.ToList(), Weather.Unknown, false, false, 0, 3, 2, 3, 2);
            ////Console.WriteLine(formation);
            //foreach (var player in lineup)
            //{
            //    Console.WriteLine(player);
            //}          

        }        
    
        void fetcher_FetchFinished(object sender, FetchResultEventArgs e)
        {
        //    WebFetcher fetcher = sender as WebFetcher;
                        
        //    //storage = new FileSystemStorage<List<string>>("../../../storages", storageId);

        //    //List<string> xmls = new List<string>();
        //    //foreach (var item in e.Cache.Xmls)
        //    //    xmls.Add(item.Value.ToString());           
        //    //storage.Write(xmls, e.MyTeam.Country.SeasonNumber.ToString());            
            

            ev.Set();
        }

        private void calcLineup()
        {
            var fetcher = new WebFetcher(readTokenFromFile(), readSecretFromFile());
            printLineup(fetcher.MyRegion(), fetcher.MyPlayers());
        }

        private void calc2ndLineup()
        {
            var fetcher = new WebFetcher(readTokenFromFile(), readSecretFromFile());
            var playerPool = fetcher.MyPlayers().ToList();
            playerPool.RemoveAll(player => player.LastMatch.MatchDate > DateTime.Now.AddDays(-6));
            printLineup(fetcher.MyRegion(), playerPool.ToEntityCollection());
        }

        void printLineup(Region myRegion, EntityCollection<Player> myPlayers)
        {
            List<Player> playerPool = myPlayers.ToList();

            var lineup = Calculations.GetLineup(playerPool, myRegion.TomorrowForecast, false, true, 0, 3, 2, 3, 2);
            var subs = Calculations.GetLineup(playerPool, myRegion.TomorrowForecast, false, false, 0, 1, 1, 1, 1);
            var penaltyShooters = Calculations.GetPenaltyShootoutOrder(lineup);
            var captain = Calculations.GetCaptain(lineup);
            var setpiecesTaker = Calculations.GetSetpiecesTaker(lineup);


            Console.WriteLine("Lineup: ");
            foreach (var player in lineup)
                Console.WriteLine(string.Format("{0} ({1:0.00})", player, player.AssignedPositionScore));
            Console.WriteLine("");

            Console.WriteLine("Subs: ");
            foreach (var player in subs)
                Console.WriteLine(string.Format("{0} ({1:0.00})", player, player.AssignedPositionScore));
            Console.WriteLine("");

            Console.WriteLine("Penalty shooters: ");
            foreach (var player in penaltyShooters)
                Console.WriteLine(player);
            Console.WriteLine("");

            Console.WriteLine("Capatin: {0}", captain);
            Console.WriteLine("Setpieces: {0}", setpiecesTaker);

            Console.WriteLine(Calculations.GetWeakestPositionInLineup(lineup));
            
        }

        public void registerWithHattrick()
        {
            DevDefinedOAuth auth = new DevDefinedOAuth(CONSUMER_KEY, readSecretFromFile());

            // only needed once
            oneTimeAuth(auth);
        }

        private void storeTokenToFile(IToken x)
        {
            BinaryFormatter bf = new BinaryFormatter();
            bf.Serialize(File.OpenWrite("mytoken.bin"), x);
        }

        private void oneTimeAuth(DevDefinedOAuth auth)
        {
            Process.Start(auth.GetAuthorizeUrl());
            IToken x = auth.ExchangeRequestTokenForAccessToken(Console.ReadLine());
            storeTokenToFile(x);
        }

        private string readSecretFromFile()
        {
            return File.ReadAllText("secret.txt");
        }

        private IToken readTokenFromFile()
        {
            BinaryFormatter bf = new BinaryFormatter();
            return bf.Deserialize(File.OpenRead("mytoken.bin")) as IToken;
        }

        private static void generateCountryIDEnum(DevDefinedOAuth auth)
        {
            // can be filterd using LeagueID =  {something}
            var xml = auth.AccessProtectedResource("http://chpp.hattrick.org/chppxml.ashx?file=worlddetails");
            var counryCollection = from league in xml.Descendants("League")
                                   orderby Convert.ToInt32(league.Element("Country").Element("CountryID").Value)
                                   select string.Format("{0} = {1},",
                                                        league.Element("EnglishName").Value.Replace(" ", ""),
                                                        league.Element("Country").Element("CountryID").Value);

            using (StreamWriter sw = File.CreateText("CountryCodes.txt"))
                foreach (var item in counryCollection)
                    sw.WriteLine(item);
        }

        private static void generateLeagueIDEnum(DevDefinedOAuth auth)
        {
            // can be filterd using LeagueID =  {something}
            var xml = auth.AccessProtectedResource("http://chpp.hattrick.org/chppxml.ashx?file=worlddetails");
            var counryCollection = from league in xml.Descendants("League")
                                   orderby Convert.ToInt32(league.Element("LeagueID").Value)
                                   select string.Format("{0} = {1},",
                                                        league.Element("LeagueName").Value.Replace(" ", ""),
                                                        league.Element("LeagueID").Value);

            using (StreamWriter sw = File.CreateText("LeagueCodes.txt"))
                foreach (var item in counryCollection)
                    sw.WriteLine(item);
        }

        private static void generateLeagueIdToCountryEnumTranslationCode(DevDefinedOAuth auth)
        {
            var xml = auth.AccessProtectedResource("http://chpp.hattrick.org/chppxml.ashx?file=worlddetails");
            var counryCollection = from league in xml.Descendants("League")
                                   orderby Convert.ToInt32(league.Element("LeagueID").Value)
                                   select new 
                                   {
                                       LeagueID = Convert.ToInt32(league.Element("LeagueID").Value),
                                       CountryName =  league.Element("EnglishName").Value.Replace(" ", ""),                                            
                                   };


            using (StreamWriter sw = File.CreateText("LeaugeIdToCountryEnum.cs"))
            {
                sw.WriteLine("switch (leagueId)");
                sw.WriteLine("{");
                
                foreach (var item in counryCollection)
                {
                    sw.WriteLine("\tcase {0}:", item.LeagueID);
                    sw.WriteLine("\t\treturn Countries.{0};", item.CountryName);
                }

                sw.WriteLine("\tdefault:");
                sw.WriteLine("\t\tthrow new ArgumentException(\"Invalid league id\", \"leagueId\");");
                sw.WriteLine("}");
            }
        }
    }
}

